package com.zndroid.base.widgets;

import android.animation.LayoutTransition;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.transition.TransitionManager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.content.ContextCompat;


import com.zndroid.base.R;

import java.util.Timer;
import java.util.TimerTask;

/**
 * 通用搜索栏控件
 *
 * @author lzy
 * @date 2021/4/16
 */
@SuppressWarnings("unused")
public class SearchLayout extends LinearLayout {
    /**搜索框文字的颜色*/
    private int searchTextColor;
    /**搜索框文字的大小*/
    private int searchTextSize;
    /**搜索框提示文字的颜色*/
    private int searchTextColorHint;
    /**按钮文字的颜色*/
    private int searchButtonColor;
    /**按钮文字的大小*/
    private int searchButtonTextSize;
    /**最外层父控件的背景颜色*/
    private int searchBackgroundColor;
    /**搜索框的背景*/
    private Drawable searchTextBackground;
    /**左边的图标*/
    private Drawable searchDrawableLeftIcon;
    /**左边的图标的距离*/
    private int searchDrawablePadding;
    /**提示文字*/
    private String searchHint = "搜索";
    /**搜索框是否单行显示*/
    private boolean searchSingleLine;
    /**搜索按钮为空字符*/
    private String searchButtonEmptyTxt = "取消";
    /**搜索按钮为空字符*/
    private String searchButtonTxt = "搜索";
    /**搜索框距离最外层的距离,若有值，以下4个属性无效*/
    private int searchPadding;
    private int searchPaddingLeft;
    private int searchPaddingTop;
    private int searchPaddingRight;
    private int searchPaddingBottom;
    /**搜索框高度*/
    private int searchHeight;
    /**键盘的选项*/
    private int searchImeOption;
    /**按钮宽度*/
    private int searchButtonWidth;

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public SearchLayout(Context context) {
        this(context, null);
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public SearchLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public SearchLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttr(context, attrs, defStyleAttr);
    }

    private ConstraintLayout constraintLayout;
    private EditText et;
    private Button bt;
    private ConstraintSet constraintSet;
    private LinearLayout parent;
    private ImageView ivClear;

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void initAttr(Context context, AttributeSet attrs, int defStyleAttr) {
        LinearLayout.inflate(context, R.layout.z_base_layout_search, this);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SearchLayout, defStyleAttr, 0);

        searchTextBackground = array.getDrawable(R.styleable.SearchLayout_search_text_background);
        searchDrawableLeftIcon = array.getDrawable(R.styleable.SearchLayout_search_drawable_left_icon);
        searchBackgroundColor = array.getColor(R.styleable.SearchLayout_search_background_color, Color.parseColor("#f0eff5"));
        searchPadding = array.getDimensionPixelSize(R.styleable.SearchLayout_search_padding, -1);
        searchPaddingLeft = array.getDimensionPixelSize(R.styleable.SearchLayout_search_padding_left, 16);
        searchPaddingTop = array.getDimensionPixelSize(R.styleable.SearchLayout_search_padding_top, 16);
        searchPaddingRight = array.getDimensionPixelSize(R.styleable.SearchLayout_search_padding_right, 16);
        searchPaddingBottom = array.getDimensionPixelSize(R.styleable.SearchLayout_search_padding_bottom, 16);
        searchTextColor = array.getColor(R.styleable.SearchLayout_search_text_color, Color.parseColor("#313131"));
        searchTextSize = array.getDimensionPixelSize(R.styleable.SearchLayout_search_text_size, 28);
        searchTextColorHint = array.getColor(R.styleable.SearchLayout_search_text_color_hint, Color.parseColor("#9a9a9c"));
        searchSingleLine = array.getBoolean(R.styleable.SearchLayout_search_single_line, true);
        searchHint = array.getString(R.styleable.SearchLayout_search_hint);
        searchDrawablePadding = array.getDimensionPixelSize(R.styleable.SearchLayout_search_drawable_padding, 10);
        searchHeight = array.getDimensionPixelSize(R.styleable.SearchLayout_search_height, 70);
        searchButtonColor = array.getColor(R.styleable.SearchLayout_search_button_color, Color.parseColor("#313131"));
        searchButtonTextSize = array.getDimensionPixelSize(R.styleable.SearchLayout_search_button_text_size, 28);
        searchButtonEmptyTxt = array.getString(R.styleable.SearchLayout_search_button_empty_txt);
        searchButtonTxt = array.getString(R.styleable.SearchLayout_search_button_txt);
        searchImeOption = array.getInt(R.styleable.SearchLayout_search_imeOption, -1);
        searchButtonWidth = array.getDimensionPixelSize(R.styleable.SearchLayout_search_button_width, ViewGroup.LayoutParams.WRAP_CONTENT);

        if (searchTextBackground == null) {
            searchTextBackground = ContextCompat.getDrawable(context, R.drawable.z_base_search_layout_bg);
        }
        if (searchDrawableLeftIcon == null) {
            searchDrawableLeftIcon = ContextCompat.getDrawable(context, R.drawable.z_base_ic_search);
        }
        if (TextUtils.isEmpty(searchHint)) {
            searchHint = "搜索";
        }
        if (TextUtils.isEmpty(searchButtonEmptyTxt)) {
            searchButtonEmptyTxt = "取消";
        }
        if (TextUtils.isEmpty(searchButtonTxt)) {
            searchButtonTxt = "搜索";
        }

        array.recycle();

        initView();
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void initView() {
        parent = findViewById(R.id.base_search_ll_parent);
        et = findViewById(R.id.base_search_et);

        constraintLayout = findViewById(R.id.base_search_constraint_layout);
        bt = findViewById(R.id.base_search_btn_exec);
        ivClear = findViewById(R.id.base_search_iv_clear);

        setValue();
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void setValue() {
        et.setTextColor(searchTextColor);
        et.setTextSize(TypedValue.COMPLEX_UNIT_PX,searchTextSize);
        et.setHintTextColor(searchTextColorHint);
        et.setSingleLine(searchSingleLine);
        et.setHint(searchHint);
        if (searchImeOption != -1){
            et.setImeOptions(searchImeOption);
        }
        searchDrawableLeftIcon.setBounds(0, 0, searchHeight/3*2, searchHeight/3*2);
        et.setCompoundDrawablePadding(searchDrawablePadding);
        et.setCompoundDrawables(searchDrawableLeftIcon, null, null, null);

        constraintLayout.setBackground(searchTextBackground);
        constraintLayout.getLayoutParams().height = searchHeight;

        bt.setTextColor(searchButtonColor);
        bt.setTextSize(TypedValue.COMPLEX_UNIT_PX,searchButtonTextSize);
        bt.getLayoutParams().width = searchButtonWidth;

        parent.setBackgroundColor(searchBackgroundColor);
        if (searchPadding != -1){
            parent.setPadding(searchPadding, searchPadding, searchPadding, searchPadding);
        }else{
            parent.setPadding(searchPaddingLeft, searchPaddingTop, searchPaddingRight, searchPaddingBottom);
        }

        ivClear.setVisibility(GONE);

        constraintSet = new ConstraintSet();
        constraintSet.clone(constraintLayout);

        initListener();
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void initListener() {
        et.setOnClickListener(v -> {
            bt.setText(searchButtonEmptyTxt);
            changeLayout(true);
        });
        constraintLayout.setOnClickListener(v -> {
            bt.setText(searchButtonEmptyTxt);
            changeLayout(true);
        });

        bt.setOnClickListener(v -> {
            if (onSearchListener != null) {
                String str = bt.getText().toString().trim();
                onSearchListener.onClick(str, str.equals(searchButtonTxt));
            }
            if (bt.getText().toString().equals(searchButtonEmptyTxt)) {
                changeLayout(false);
                et.setText("");
            } else {
                setSoftInput(false);
            }
        });

        et.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (TextUtils.isEmpty(s.toString())) {
                    bt.setText(searchButtonEmptyTxt);
                    ivClear.setVisibility(GONE);
                } else {
                    bt.setText(searchButtonTxt);
                    ivClear.setVisibility(VISIBLE);
                }

                if (null != onSearchTextChangeListener) {
                    onSearchTextChangeListener.onTextChanged(s.toString());
                }
            }
        });

        addEditorActionListener();

        ivClear.setOnClickListener(v -> et.setText(""));

        setEditTextState(false);
    }

    /**添加键盘回车键监听器*/
    private void addEditorActionListener() {
        if (searchImeOption != -1){
            et.setOnEditorActionListener((v, actionId, event) -> {
                if (onEditorActionListener != null){
                    onEditorActionListener.onEditorAction(v, actionId, event);
                }
                return false;
            });
        }
    }

    /**设置输入框状态，canInput为true是输入框移至左侧，自动弹出键盘，否则反之*/
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public void changeLayout(boolean canInput) {
        TransitionManager.beginDelayedTransition(constraintLayout);
        parent.setLayoutTransition(canInput ? new LayoutTransition() : null);
        constraintSet.constrainWidth(R.id.base_search_et, canInput ? constraintLayout.getLayoutParams().width : LayoutParams.WRAP_CONTENT);
        constraintSet.applyTo(constraintLayout);

        setEditTextState(canInput);
    }

    private void setEditTextState(final boolean isFocusable){
        bt.setVisibility(isFocusable?View.VISIBLE:View.GONE);
        //可以通过键盘得到焦点
        et.setFocusable(isFocusable);
        //可以通过触摸得到焦点
        et.setFocusableInTouchMode(isFocusable);
        if (isFocusable){
            //获取焦点 光标出现
            et.requestFocus();
        }else{
            et.clearFocus();
        }

        setSoftInput(isFocusable);
    }

    /**设置键盘弹出、收起*/
    public void setSoftInput(final boolean isFocusable) {
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                InputMethodManager m = (InputMethodManager)et.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                if (isFocusable) {
                    m.showSoftInput(et, InputMethodManager.SHOW_FORCED);
                } else {
                    m.hideSoftInputFromWindow(et.getWindowToken(), 0);
                }
            }
        }, 300);
    }

    /**设置键盘回车键事件*/
    public void setImeOptions(int imeOptions){
        et.setImeOptions(imeOptions);
        addEditorActionListener();
    }

    private OnSearchListener onSearchListener;
    public void setOnSearchListener(OnSearchListener onSearchListener) {
        this.onSearchListener = onSearchListener;
    }

    private OnEditorActionListener onEditorActionListener;
    public void setOnEditorActionListener(OnEditorActionListener onEditorActionListener){
        this.onEditorActionListener = onEditorActionListener;
    }

    private OnSearchTextChangeListener onSearchTextChangeListener;
    public void setOnSearchTextChangeListener(OnSearchTextChangeListener onSearchTextChangeListener){
        this.onSearchTextChangeListener = onSearchTextChangeListener;
    }

    public interface OnSearchTextChangeListener {
        /**
         * call back on click
         * @param s string
         * */
        void onTextChanged(String s);
    }

    public interface OnSearchListener {
        /**
         * call back on click
         * @param str string
         * @param isSearch pressed by search
         * */
        void onClick(String str, boolean isSearch);
    }
    public interface OnEditorActionListener {
        /**
         * keyboard event
         * @param view current view
         * @param actionId action id
         * @param event event
         * @return true or false
         * */
        boolean onEditorAction(TextView view, int actionId, KeyEvent event);
    }
}